'use strict'

let dbUtil = require('../util/dbUtil');
let authUtil = require('../util/authUtil');
let mysqlUtil = require('../util/mysqlUtil');
let sha256 = require('../util/sha256');
let base64 = require('../util/base64');
let EventProxy = require('eventproxy');
let Q = require('q');
let fs = require('fs');
let constants = require('../util/constants');
let upgradePackageService = require('../service/upgradePackageService');
let rd = require('rd');

/**
 * 查询
 */
let query = (req, res) => {
    let sql = "select up.*, date_format(up.create_time,'%Y-%m-%d %T') as create_time_display, ";
    sql += "(select group_concat(pro.name) from t_ug_package_project upp left join t_ug_project pro on pro.id = upp.project_id where upp.package_id=up.id) as bind_projects, ";
    sql += "(select count(1) from t_ug_package_file upf where upf.package_id=up.id) file_count ";
    sql += "from t_ug_package up where 1=1 ";

    let searchVal = mysqlUtil.paramFilter(req.body.searchVal);

    if (req.body.confirm_publish != null && req.body.confirm_publish != '') {
        sql += " and up.is_publish=" + mysqlUtil.escape(req.body.confirm_publish);
    }
    if (req.body.packageProjectId != null && req.body.packageProjectId != '') {
        sql += " and exists (select 1 from t_ug_package_project upp where upp.package_id=up.id and upp.project_id=" + mysqlUtil.escape(req.body.packageProjectId) + ")";
    }
    if (searchVal != null && searchVal != '') {
        sql += " and (up.appname_en like '%" + searchVal + "%' or up.appname_cn like '%" + searchVal + "%' or up.module like '%" + searchVal + "%' or up.description like '%" + searchVal + "%'";
        sql += " or exists (select 1 from t_ug_package_file upf where upf.package_id=up.id and upf.file_name like '%" + searchVal + "%'))";
    }

    sql += " order by up.create_time desc";

    dbUtil.partitionQuery(sql, req, res);
};

/**
 * 删除
 */
let remove = (req, res) => {
    upgradePackageService.remove(req, res);
};

/**
 * 批量修改升级包
 */
let toBatchUpPackage = (req, res) => {
    var ids = req.query.ids;

    var _getInfo = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package where id in (?)", [ids.split(',')], (err, result) => {
            deferred.resolve(result);
        });
        return deferred.promise;
    };

    _getInfo().done(function(data) {
        res.render('upgradePackage/toBatchUpPackage', { packages: data });
    });
};

/**
 *  处理批量修改升级包
 */
let doBatchUpPackage = (req, res) => {
    let packagesJson = req.body.packagesJson;

    let _updateInfo = () => {
        let deferred = Q.defer();
        var packages = JSON.parse(packagesJson);

        let sqlObjs = [];
        for (var i = 0; i < packages.length; i++) {
            sqlObjs.push({ sql: 'update t_ug_package set description=?, module=? where id=?', values: [packages[i].description, packages[i].module, packages[i].id] });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updateInfo().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    });
};


/**
 * 批量修改升级包测试结果
 */
let toUpdateTestResult = (req, res) => {
    var ids = req.query.ids;

    var _getInfo = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package where id in (?)", [ids.split(',')], (err, result) => {
            deferred.resolve(result);
        });
        return deferred.promise;
    };

    _getInfo().done(function(data) {
        res.render('upgradePackage/toUpdateTestResult', { packages: data });
    });
};

/**
 *  处理批量修改升级包测试结果
 */
let doUpdateTestResult = (req, res) => {
    let packagesJson = req.body.packagesJson;

    let _updateInfo = () => {
        let deferred = Q.defer();
        var packages = JSON.parse(packagesJson);

        let sqlObjs = [];
        for (var i = 0; i < packages.length; i++) {
            sqlObjs.push({
                sql: 'update t_ug_package set defect_count=?, high_defect_count=?, rework_count=?, demand_point_count=? where id=?',
                values: [packages[i].defect_count, packages[i].high_defect_count, packages[i].rework_count, packages[i].demand_point_count, packages[i].id]
            });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _updateInfo().done(data => {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    });
};


/**
 * 绑定项目
 */
let toBindProject = (req, res) => {
    res.render('upgradePackage/toBindProject', { id: req.query.id });
};

/**
 * 处理绑定项目
 */
let doBindProject = (req, res) => {
    let projectsJson = req.body.projectsJson;
    let packageId = req.body.id;

    let _delRefProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec('delete from t_ug_package_project where package_id=?', [packageId], (err, result) => {
            deferred.resolve();
        });
        return deferred.promise;
    };

    let _insRefProjects = () => {
        let deferred = Q.defer();
        var projects = JSON.parse(projectsJson);

        let sqlObjs = [];
        for (var i = 0; i < projects.length; i++) {
            sqlObjs.push({ sql: 'insert into t_ug_package_project(id, package_id, project_id) values(uuid(), ?, ?)', values: [packageId, projects[i].id] });
        }

        mysqlUtil.exec_batch(sqlObjs, null, function() {
            deferred.resolve();
        });
        return deferred.promise;
    };

    _delRefProjects().then(_insRefProjects).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

/**
 * 获取升级包关联的项目
 */
let getPackageProject = (req, res) => {
    var id = req.query.id;

    var output = {};

    var _getRelationProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select p.id, p.name from t_ug_package_project upp left join t_ug_project p on p.id = upp.project_id where upp.package_id=?", [id], (err, result) => {
            output.relationProjects = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    var _getUnRelationProjects = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select id, name from t_ug_project p where p.id not in (select upp.project_id from t_ug_package_project upp where upp.package_id=?)", [id], (err, result) => {
            output.unRelationProjects = result;
            deferred.resolve();
        });
        return deferred.promise;
    };

    _getRelationProjects().then(_getUnRelationProjects).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(output));
    });
};

/**
 * 进入上传升级包页面
 */
let toUpload = (req, res) => {
    let deferred = Q.defer();

    // 检查上传文件路径
    let _checkFilePath = () => {
        mysqlUtil.exec("select * from t_config where name=?", [constants.UPGRADE_PACKAGE_FILE_PATH], (err, result) => {
            if (result.length == 0) {
                deferred.reject("Haven't configure the path of the upload"); // 还没有配置上传路径
            } else {
                let folder_exists = fs.existsSync(result[0].value);
                if (!folder_exists) {
                    deferred.reject("Configuration of the upload path is wrong"); //配置的上传路径有误
                } else {
                    deferred.resolve(result[0].value);
                }
            }
        });
        return deferred.promise;
    };

    _checkFilePath().done(data => {
        res.render('upgradePackage/toUpload', {});
    }, data => {
        console.log(data);
        res.render('404_dialog', { errMsg: data });
    });

};

/**
 * 处理上传升级包
 */
let doUpload = (req, res) => {
    upgradePackageService.doUpload(req, res);
};

/**
 * 查看上传的升级包信息
 */
let uploadInfo = (req, res) => {
    let packageId = req.query.id;

    let _getUpgradePackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package where id=?", [packageId], (err, result) => {
            deferred.resolve(result[0]);
        });
        return deferred.promise;
    };

    let _getUpgradePackageFiles = data => {
        let deferred = Q.defer();

        mysqlUtil.exec("select * from t_ug_package_file where package_id=? order by file_name", [packageId], (err, result) => {
            for (let packageFile of result) {
                packageFile.file_path = packageFile.file_path.substring(packageFile.file_path.indexOf(constants.PATH_SEPARATOR + data.appname_en + constants.PATH_SEPARATOR), packageFile.file_path.length);
                packageFile.canPreview = canPreview(packageFile.file_name.substring(packageFile.file_name.lastIndexOf('.') + 1, packageFile.file_name.length));
            }

            let obj = { package: data, packageFiles: result };
            deferred.resolve(obj);
        });
        return deferred.promise;
    };

    _getUpgradePackage().then(_getUpgradePackageFiles).done(data => {
        res.render('upgradePackage/uploadInfo', data);
    });
};

/**
 * 预览文件
 */
let previewFile = (req, res) => {
    let id = req.query.id;

    let _getFilePath = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package_file where id=?", [id], (err, result) => {
            if (err || result.length == 0) {
                res.render('404', { errMsg: 'Can\'t find the file.' });
                return;
            }
            deferred.resolve({
                filePath: result[0].file_path,
                fileName: result[0].file_name
            });
        });
        return deferred.promise;
    };

    _getFilePath().done(d => {
        fs.readFile(d.filePath, 'utf-8', function(err, data) {
            if (err) {
                res.render('404', { errMsg: 'File read error.' });
            } else {
                var obj = {
                    content: data,
                    filePath: d.filePath,
                    fileName: d.fileName
                };
                res.render('upgradePackage/previewFile', obj);
            }
        });
    });
};

/**
 * 下载单个文件
 */
let downloadFile = (req, res) => {
    let id = req.query.id;

    let _getFilePath = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package_file where id=?", [id], (err, result) => {
            if (err || result.length == 0) {
                res.render('404', { errMsg: 'Can\'t find the file.' });
                return;
            }
            deferred.resolve({ filePath: result[0].file_path, fileName: result[0].file_name });
        });
        return deferred.promise;
    };
    _getFilePath().done(d => {
        res.download(d.filePath);
    });
};

/**
 * 下载上传的压缩包
 */
let downloadZipFile = (req, res) => {
    let id = req.query.id;

    let _getFilePath = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_upgrade_package where id=?", [id], (err, result) => {
            if (err || result.length == 0) {
                res.render('404', { errMsg: 'Can\'t find the file.' });
                return;
            }
            deferred.resolve({ filePath: result[0].original_file_path, fileName: result[0].original_file_name });
        });
        return deferred.promise;
    };
    _getFilePath().done(d => {
        res.download(d.filePath);
    });
};

/**
 * 删除上传的压缩包及相关文件
 */
let removeZipFile = (req, res) => {
    upgradePackageService.removePackageFile(req, res);
};

/**
 * 发布升级包
 */
let publish = (req, res) => {
    let id = req.body.id;

    let _getPackage = () => {
        let deferred = Q.defer();
        mysqlUtil.exec("select * from t_ug_package where id=?", [id], (err, result) => {
            if (err || result.length == 0) {
                res.render('404', { errMsg: 'Can\'t find the upgrade package.' });
                return;
            }
            deferred.resolve(result[0]);
        });
        return deferred.promise;
    };

    let _checkSequence = (data) => {
        let deferred = Q.defer();
        mysqlUtil.exec("select count(1) c from t_sequence where name=?", [data.appname_en], (err, result) => {
            var c = result[0].c;
            if (c == 0) {
                mysqlUtil.exec("insert into t_sequence(name, current_value, increment) values(?, 0, 1)", [data.id], (err, result) => {
                    deferred.resolve(data);
                });
            } else {
                deferred.resolve(data);
            }
        });
        return deferred.promise;
    };

    let _updatePackage = (data) => {
        let deferred = Q.defer();
        let sql = "update t_ug_package set version=nextval('" + data.id + "'), is_publish=1 where id=?";
        mysqlUtil.exec(sql, [data.id], (err, result) => {
            deferred.resolve(data);
        });
        return deferred.promise;
    };

    _getPackage().then(_checkSequence).then(_updatePackage).done(function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: true }));
    }, function() {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ success: false }));
    });
};

// ------------------------------------------------------------
let canPreview = suffix => {
    let formats = 'jsp,sql,java,js,css,txt,xml,ini,html,htm,eda,edm,epm,epg';
    let formats_arr = formats.split(',');
    for (let f of formats_arr) {
        if (f == suffix.toLowerCase()) return true;
    }
    return false;
};

exports.query = query;
exports.toBatchUpPackage = toBatchUpPackage;
exports.doBatchUpPackage = doBatchUpPackage;
exports.toUpdateTestResult = toUpdateTestResult;
exports.doUpdateTestResult = doUpdateTestResult;
exports.toBindProject = toBindProject;
exports.doBindProject = doBindProject;
exports.getPackageProject = getPackageProject;
exports.remove = remove;
exports.toUpload = toUpload;
exports.doUpload = doUpload;
exports.uploadInfo = uploadInfo;
exports.previewFile = previewFile;
exports.downloadFile = downloadFile;
//exports.downloadZipFile = downloadZipFile;
//exports.removeZipFile = removeZipFile;
exports.publish = publish;